home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / c / ExtrasLib.lha / ExtrasLib / Source / UnpackData.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-30  |  3.8 KB  |  184 lines

  1. #include <clib/extras/packdata_protos.h>
  2. #include <clib/extras/string_protos.h>
  3.  
  4. #include <proto/exec.h>
  5. #include <proto/utility.h>
  6.  
  7. #include <extras/packdata.h>
  8. #include <math.h>
  9. #include <exec/memory.h>
  10. #include <string.h>
  11. #include <tagitemmacros.h>
  12.  
  13. #define ALIGN(I)  (((I)+1)&(~1))
  14.  
  15. #define YANKBYTE(PDATA,INDEX,STORAGE,TYPE)   \
  16. {\
  17.   TYPE *store;\
  18. \
  19.   store=((TYPE *)STORAGE);\
  20.   if(store)\
  21.   {\
  22.     *store=*((TYPE *)(&((PDATA)->pd_Data[INDEX])));\
  23.   }\
  24.   (INDEX)+=sizeof(TYPE);\
  25. }\
  26.  
  27. #define YANKDATA(PDATA,INDEX,STORAGE,TYPE)   \
  28. {\
  29.   TYPE *store;\
  30. \
  31.   store=((TYPE *)STORAGE);\
  32.   INDEX=ALIGN(INDEX);\
  33.   if(store)\
  34.   {\
  35.     *store=*((TYPE *)(&((PDATA)->pd_Data[INDEX])));\
  36.   }\
  37.   (INDEX)+=sizeof(TYPE);\
  38. }\
  39.  
  40. extern ULONG PDO;
  41.  
  42. LONG pd_UnpackData(struct PackedData *PD, Tag Tags, ...)
  43. {
  44.   struct TagItem *tag,*tstate;
  45.   LONG i=0,data,aptrsize,structsize,memflags,version,freestrptr=0;
  46.   BYTE **dptr;
  47.  
  48.   ULONG pdo;
  49.   struct TagItem mytags[]=
  50.   {
  51.     PD_StructSize, 0,
  52.     PD_Struct,     0,
  53.     TAG_MORE,      0
  54.   };
  55.   
  56.   mytags[0].ti_Data=sizeof(pdo),
  57.   mytags[1].ti_Data=&pdo,
  58.   mytags[2].ti_Data=(ULONG)&Tags;
  59.  
  60.  
  61.   memflags=0;
  62.   version=0;
  63.  
  64.   if(PD)
  65.   {
  66.     if(PD->pd_Data)
  67.     {
  68.       ProcessTagList((struct TagItem *)&mytags,tag,tstate)
  69.       {
  70.         data=tag->ti_Data;
  71.         dptr=(BYTE **)data;
  72.         switch(tag->ti_Tag)
  73.         {
  74.           case PD_FreeSTRPTR:
  75.             freestrptr=data;
  76.             break;
  77.             
  78.           case PD_Version: // It's a ULONG
  79.             YANKDATA(PD,i,&version,ULONG);
  80.             if(dptr)
  81.             {
  82.               *((ULONG *)dptr)=version;
  83.             }
  84.             break;
  85.     
  86.           case PD_BYTE:
  87.             YANKBYTE(PD,i,data,BYTE);
  88.             break;
  89.     
  90.           case PD_UBYTE:
  91.             YANKBYTE(PD,i,data,UBYTE);
  92.             break; 
  93.     
  94.           case PD_WORD:
  95.             YANKDATA(PD,i,data,WORD);
  96.             break;
  97.     
  98.           case PD_UWORD:
  99.             YANKDATA(PD,i,data,UWORD);
  100.             break;
  101.     
  102.           case PD_LONG:
  103.             YANKDATA(PD,i,data,LONG);
  104.             break;
  105.     
  106.           case PD_ULONG:
  107.             YANKDATA(PD,i,data,ULONG);
  108.             break;
  109.     
  110.           case PD_STRPTR:
  111.             {
  112.               LONG sl;
  113.               
  114.               i=ALIGN(i);
  115.               sl=strlen((STRPTR)&PD->pd_Data[i])+1;
  116.               if(dptr)
  117.               {
  118.                 if(*dptr && freestrptr) 
  119.                   FreeVec(*dptr);
  120.                 
  121.                 *dptr=CopyString(&PD->pd_Data[i],memflags); // WARNING no error code!
  122.               }
  123.               i+=sl;
  124.             }
  125.             break;
  126.  
  127.           case PD_APTRSize:
  128.             YANKDATA(PD,i,&aptrsize,LONG); 
  129.             i-=4; // Backup 4 bytes
  130.             YANKDATA(PD,i,data,ULONG);
  131.             break;
  132.  
  133.           case PD_APTR:
  134.             i=ALIGN(i);
  135.             
  136.             if(dptr)
  137.             {  
  138.               if(*dptr=AllocVec(aptrsize,memflags)) // WARNING no error code!
  139.               {
  140.                 CopyMem((&PD->pd_Data[i]),*dptr,aptrsize); 
  141.               }
  142.             }
  143.             i+=aptrsize;
  144.             break;
  145.  
  146.           case PD_BufferSize:
  147.             structsize=data;
  148.             break;
  149.  
  150.           case PD_Buffer:
  151.             i=ALIGN(i);
  152.             {
  153.               ULONG datasize;
  154.             
  155.               YANKDATA(PD,i,&datasize,LONG);
  156.               
  157.               if(dptr)
  158.               { 
  159.                 CopyMem((&PD->pd_Data[i]),dptr,min(datasize,structsize)); 
  160.               }
  161.               i+=datasize;
  162.             }
  163.             break;
  164.             
  165.             
  166.           case PD_MemoryFlags:
  167.             memflags=data;
  168.             break;
  169.             
  170.           case PD_IfVersion:
  171.             if(version<data)
  172.               return(0);
  173.             break;
  174.               
  175.           default:
  176.             /* ERROR */
  177.             return(-1);
  178.         }
  179.       }
  180.     }
  181.   }
  182.   return(0);
  183. }
  184.